import { reqEditorMultioperation, reqGetOneTileService, reqGetSetting, reqRandomfeature } from '@/api';
import axios from "axios";
import { ElMessage } from "element-plus";
import { createNextAnimateFrameEvent, Destroyable, Event, HasOwner, ObjResettingWithEvent, react, reactJson } from "earthsdk3";
import { ESRtsTileset } from "earthsdk3";
// import { ESRtsTileset2 } from "../esobjs/ESRtsTileset2";

import { PolylinesWrapper } from "../esobjs/polylinesWrapper";
import { MyProjectManager } from "../MyProjectManager";
// @ts-ignore
import { VirtualLayer } from "./virtualLayer";
import { WaterMend } from "./waterMend";
// @ts-ignore
import { getUrlParam } from "@/scripts/utils";
import { BatchSet } from "./batchSet";
import { FeatureEdit } from "./featureEdit";
import { FeatureSelect } from "./featureSelect";
import { SwitchCimrts } from "./switchCimrts";
import { MaterailsManager } from './materailsManager';
import loading from '@/api/loading';

class CimrtsResettting extends Destroyable {
    constructor(tileServiceName: string, cimrtsManager: CimrtsManager, owner: MyProjectManager) {
        super();
        cimrtsManager.virtualLayer = new VirtualLayer(tileServiceName, owner);
        cimrtsManager.waterMend = new WaterMend(tileServiceName, owner);
        cimrtsManager.batchSet = new BatchSet(tileServiceName, owner);
        cimrtsManager.featureEdit = new FeatureEdit(tileServiceName, owner);
        cimrtsManager.featureSelect = new FeatureSelect(tileServiceName, owner);
        cimrtsManager.materailsManager = new MaterailsManager(tileServiceName, owner);
    }
}

export class CimrtsManager extends HasOwner<MyProjectManager> {
    //切片服务ip
    private _cimrtsIp = this.dv(react<string>(""));
    get cimrtsIp() { return this._cimrtsIp.value; }
    get cimrtsIpChanged() { return this._cimrtsIp.changed; }
    set cimrtsIp(value: string) { this._cimrtsIp.value = value; }

    // 切片服务名称
    private _tileServiceName = this.dv(react<string>(""));
    get tileServiceName() { return this._tileServiceName.value; }
    get tileServiceNameChanged() { return this._tileServiceName.changed; }
    set tileServiceName(value: string) { this._tileServiceName.value = value; }

    // 服务路径
    private _cimrtsUrl = this.dv(react<string>(""));
    get cimrtsUrl() { return this._cimrtsUrl.value; }
    get cimrtsUrlChanged() { return this._cimrtsUrl.changed; }
    set cimrtsUrl(value: string) { this._cimrtsUrl.value = value; }

    // 是不是有授权
    private _isAuth = this.dv(react<boolean>(false));
    get isAuth() { return this._isAuth.value; }
    get isAuthChanged() { return this._isAuth.changed; }
    set isAuth(value: boolean) { this._isAuth.value = value; }

    // 是不是cimrts服务
    private _isCimrtsService = this.dv(react<boolean>(false));
    get isCimrtsService() { return this._isCimrtsService.value; }
    get isCimrtsServiceChanged() { return this._isCimrtsService.changed; }
    set isCimrtsService(value: boolean) { this._isCimrtsService.value = value; }

    // cimrtsToken 是否启用
    private _cimrtsTokenEnable = this.dv(react<boolean>(false));
    get cimrtsTokenEnable() { return this._cimrtsTokenEnable.value; }
    get cimrtsTokenEnableChanged() { return this._cimrtsTokenEnable.changed; }
    set cimrtsTokenEnable(value: boolean) { this._cimrtsTokenEnable.value = value; }

    // cimrtsToken 
    private _cimrtsToken = this.dv(react<string>(""));
    get cimrtsToken() { return this._cimrtsToken.value; }
    get cimrtsTokenChanged() { return this._cimrtsToken.changed; }
    set cimrtsToken(value: string) { this._cimrtsToken.value = value; }

    // 切片服务信息
    private _tileServiceInfo = this.dv(reactJson<any>({}));
    get tileServiceInfo() { return this._tileServiceInfo.value; }
    get tileServiceInfoChanged() { return this._tileServiceInfo.changed; }
    set tileServiceInfo(value: any) { this._tileServiceInfo.value = value; }

    // 环境光散射强度
    private _atmosphereScatteringIntensity = this.dv(react<number>(2));
    get atmosphereScatteringIntensity() { return this._atmosphereScatteringIntensity.value; }
    get atmosphereScatteringIntensityChanged() { return this._atmosphereScatteringIntensity.changed; }
    set atmosphereScatteringIntensity(value: number) { this._atmosphereScatteringIntensity.value = value; }

    // 亮度
    private _brightness = this.dv(react<number>(1));
    get brightness() { return this._brightness.value; }
    get brightnessChanged() { return this._brightness.changed; }
    set brightness(value: number) { this._brightness.value = value; }

    // 清除cimrts窗口
    private _clearCimrtsWindowEvent = this.dv(new Event());
    get clearCimrtsWindowEvent() { return this._clearCimrtsWindowEvent; }

    // 材质管理吸取事件
    private _absorbEvent = this.dv(new Event<[boolean]>());
    get absorbEvent() { return this._absorbEvent; }

    // ESRtsTileset
    private _eSRtsTileset = this.dv(this.owner.createSceneObject(ESRtsTileset) as ESRtsTileset);
    // private _eSRtsTileset = this.dv(this.owner.createSceneObject(ESRtsTileset2) as ESRtsTileset2);
    get eSRtsTileset() { return this._eSRtsTileset; }

    // 折线集合
    private _polylinesWrapper = this.dv(new PolylinesWrapper(this.owner));
    get polylinesWrapper() { return this._polylinesWrapper; }

    // 虚拟图层
    private _virtualLayer: undefined | VirtualLayer = undefined;
    get virtualLayer() { return this._virtualLayer; }
    set virtualLayer(value: VirtualLayer | undefined) { this._virtualLayer = value; }

    // 水面修补
    private _waterMend: undefined | WaterMend = undefined;
    get waterMend() { return this._waterMend; }
    set waterMend(value: WaterMend | undefined) { this._waterMend = value; }

    // 批量放置
    private _batchSet: undefined | BatchSet = undefined;
    get batchSet() { return this._batchSet; }
    set batchSet(value: BatchSet | undefined) { this._batchSet = value; }

    // 要素编辑 
    private _featureEdit: undefined | FeatureEdit = undefined;
    get featureEdit() { return this._featureEdit; }
    set featureEdit(value: FeatureEdit | undefined) { this._featureEdit = value; }

    // 框选要素 
    private _featureSelect: undefined | FeatureSelect = undefined;
    get featureSelect() { return this._featureSelect; }
    set featureSelect(value: FeatureSelect | undefined) { this._featureSelect = value; }

    // 材质管理 
    private _materailsManager: undefined | MaterailsManager = undefined;
    get materailsManager() { return this._materailsManager; }
    set materailsManager(value: MaterailsManager | undefined) { this._materailsManager = value; }

    // 切换modelser服务
    private _switchCimrts = this.dv(new SwitchCimrts(this.owner));
    get switchCimrts() { return this._switchCimrts; }

    // 根据切片服务名称获取切片服务列表
    async getOneTileService() {
        const res = await reqGetOneTileService(this.tileServiceName)
        // @ts-ignore
        if (res.status != 'ok') return;
        this.tileServiceInfo = res.data
    }

    // 设置边框
    setBorder() {
        const lonLatboundingbox = this._tileServiceInfo.value?.lonLatboundingbox
        if (!lonLatboundingbox || !Object.entries(lonLatboundingbox).length) return;
        this.polylinesWrapper.setLines(lonLatboundingbox)
    }

    // 设置切片服务名称
    setTileServiceName(url: string) {
        const u1 = url.match(/\/ts\/info\/(.*)/)?.[1]
        const u2 = url.match(/\/ts\/tss\/info\/(.*)/)?.[1]
        if (u1) {
            return u1
        } else if (u2) {
            return u2
        }
    }
    // 设置切片服务ip
    setTileServiceIp(url: string) {
        return url.match(/^(https?:\/\/[^\/]+)/)?.[0] as string
    }

    // 获取cimrts配置
    async getCimrtsSetting() {
        try {
            const res = await reqGetSetting() as any
            if (res.status != "ok") return;
            // EarthDSToken开启
            if (res.data.useEarthDSToken) {
                this.cimrtsTokenEnable = true
                this.eSRtsTileset.useEarthDSToken = true
                this.eSRtsTileset.earthdstoken = this.cimrtsToken
                if (!this.cimrtsToken) {
                    ElMessage({
                        message: '权限验证已开启，但没有携带Token，请检查权限',
                        type: 'error',
                        duration: 60000,
                    })
                }
            } else {
                this.cimrtsTokenEnable = false
            }
            // this.port = res.data.port
        } catch (error) {
            console.error(error);
        }

    }

    // 处理绘制对象多边形 点位等高
    async handleDrawObjectMultioperation(root: any) {
        root.map((item: any) => {
            // 不是文件夹
            if (item.sceneObj && item.sceneObj.type == "ESRtsPolygon") {
                const max = this.owner.modelserManager.editPolygon.getMaxHeight(item.sceneObj.points)
                const min = this.owner.modelserManager.editPolygon.getMinHeight(item.sceneObj.points)

                if (item.sceneObj.isHeightEqual) {
                    item.sceneObj.points = item.sceneObj.points.map((point: any) => [point[0], point[1], (max + min) / 2])
                }
            }
            // 如果有子项，递归调用并合并结果
            if (item.children && item.children.length > 0) {
                this.handleDrawObjectMultioperation(item.children)
            }
        })
    }

    // 提交正在编辑的对象
    async submitEditorMultioperation() {
        try {

            const json = this.owner.cimrtsSceneTreeWrapper?.json.root.children
            this.handleDrawObjectMultioperation(json)

            const param = {
                "tileServiceName": this.tileServiceName,
                "sceneTree": json
            }
            const res = await reqEditorMultioperation(param)
            // @ts-ignore
            if (res.status != 'ok') {
                loading.closeLoading()
                ElMessage({
                    message: "提交失败",
                    type: 'error',
                })
                return;
            }
            loading.closeLoading()
            ElMessage({
                message: `要素编辑成功${res.data.featureEditSucess}个，失败${res.data.featureEditFail}个；批量放置成功${res.data.batchCreateSucess}个，
                失败${res.data.batchCreateFail}个；绘制对象成功${res.data.waterRepairSucess}个，失败${res.data.waterRepairFail}个`,
                type: 'success',
            })
            this.owner.cimrtsSceneTreeWrapper?.destroyAllSceneObjectTreeItems()
            this.owner.propSceneTree = undefined
            this.featureEdit && (this.featureEdit.innerFields = [])
            this.eSRtsTileset.refresh();
        } catch (error) {
            loading.closeLoading()
            console.error(error);
        }
    }

    // 验证是不是cimrts服务
    async verifyCimrtsService() {
        try {
            // 添加请求头
            const token = localStorage.getItem("Authorization")
            const res2 = await axios({
                url: this.cimrtsUrl,
                method: 'get',
                headers: {
                    ...(token ? { 'Authorization': token } : {})
                },
            })

            if (res2.data.data && res2.data.data.hasOwnProperty("boundingbox")) {
                // 有授权
                if (res2.data.data.authinfo) {
                    this.isAuth = true
                }
                // 没有授权
                else {
                    this.isAuth = false
                    ElMessage({
                        dangerouslyUseHTMLString: true,
                        message: '<strong>无授权，无法切片，无法展示模型，请跳转 <a style="color: #3385ff;text-decoration: none;"  href="https://account.bjxbsj.cn/" target="_blank">https://account.bjxbsj.cn/</a> 进行注册并申请授权 </strong>',
                        type: 'error',
                        duration: 60000,
                    })
                }
                await this.getCimrtsSetting()

                this.isCimrtsService = true
                // eSRtsTileset url
                this.eSRtsTileset.url = this.cimrtsUrl
                // 获取切片服务信息
                // await this.getOneTileService()
                this.tileServiceInfo = res2.data.data
                // 设置边界
                this.setBorder()
            } else {
                this.isCimrtsService = false
                this.eSRtsTileset.url = ""
                ElMessage.error('请输入正确的Cimrts服务地址')
            }

        } catch (error) {
            this.isCimrtsService = false
            this.eSRtsTileset.url = ""
            ElMessage.error('请输入正确的Cimrts服务地址')
            return false
        }

    }

    // 随机返回一个要素信息(用于定位)
    async randomfeature() {
        try {
            const param = {
                "tileServiceName": this.tileServiceName,
            }
            const res = await reqRandomfeature(param)
            // @ts-ignore
            if (res.status != 'ok') return;
            const { boundingbox, lonLatboundingbox } = res.data
            const radius = boundingbox.sphereRadius * 3 + boundingbox.maxZ
            const rectangle: [number, number, number, number] = [lonLatboundingbox.minX, lonLatboundingbox.minY, lonLatboundingbox.maxX, lonLatboundingbox.maxY]
            this.owner.activeViewer?.flyToBoundingSphere(rectangle, radius)

        } catch (error) {

        }
    }

    clear() {
        // 是否是cimrts服务
        this.isCimrtsService = false
        // 清除cimrts窗口
        this.clearCimrtsWindowEvent.emit()
        // 清除切片服务信息
        this.tileServiceInfo = {}
        // 场景树上的对象删除
        this.owner.cimrtsSceneTreeWrapper?.destroyAllSceneObjectTreeItems()
        this.owner.propSceneTree = undefined
    }

    constructor(owner: MyProjectManager) {
        super(owner);
        {
            const updata = async (url: string) => {
                // 清除参数
                this.clear()
                if (!url) {
                    this.eSRtsTileset.url = ""
                    return;
                }

                // 验证是不是Cimrts服务
                const flag = await this.verifyCimrtsService()
                // 设置切片服务名称
                this.tileServiceName = this.setTileServiceName(url) as string
                // 设置切片服务ip
                this.cimrtsIp = this.setTileServiceIp(url)
            }
            this.dispose(this.cimrtsUrlChanged.don(updata))
        }

        {
            const event = this.dv(createNextAnimateFrameEvent(this.cimrtsUrlChanged, this.isCimrtsServiceChanged, this.isAuthChanged));
            this.dv(new ObjResettingWithEvent(event, () => {
                // 没有授权
                if (!this.isAuth) return undefined;
                // cimrts服务地址为空
                if (!this.cimrtsUrl) return undefined;
                // 不是Cimrts服务
                if (!this.isCimrtsService) return undefined;
                return new CimrtsResettting(this.tileServiceName, this, this.owner);

            }))
        }

        {
            const updata = () => {
                this.eSRtsTileset.es3DTileset.czmEnvironmentMapManager = {
                    atmosphereScatteringIntensity: this.atmosphereScatteringIntensity,
                    brightness: this.brightness
                }
            }
            updata()
            this.ad(this.atmosphereScatteringIntensityChanged.don(updata))
            this.ad(this.brightnessChanged.don(updata))
        }
        {
            const obj = getUrlParam();
            this.dispose(this.eSRtsTileset.es3DTileset.tilesetReady.disposableOnce(() => {
                if (obj.hasOwnProperty("cameraInfo")) return;
                this.eSRtsTileset.es3DTileset.flyTo()
            }))
        }
    }
}